---
title: "Building Custom Agents"
description: "Extend and customize the agent framework"
icon: "code"
---

While the MCPAgent provides a complete, ready-to-use solution, you may want to build custom agents for specialized use cases, integration with existing systems, or advanced behavior.

## Why Build Custom Agents?

Build custom agents when you need:

- **Specialized behavior**: Implement domain-specific logic or workflows
- **Integration**: Connect with existing agent frameworks or systems
- **Advanced control**: Fine-tune every aspect of agent behavior
- **Unique patterns**: Implement custom decision-making or tool selection logic

<Tip>
**Start with MCPAgent**: Before building a custom agent, consider if the built-in `MCPAgent` can meet your needs with configuration options like custom system prompts, structured output, or server manager.
</Tip>

## Architecture Overview

Building custom agents with mcp-use involves:

<CardGroup cols={3}>
  <Card title="Access Tools" icon="plug">
    Connect to powerful MCP tools through flexible connectors
  </Card>
  <Card title="Convert & Adapt" icon="arrows-rotate">
    Transform MCP tools to work with any agent framework via adapters
  </Card>
  <Card title="Build Agents" icon="robot">
    Create specialized agents tailored to your specific use cases
  </Card>
</CardGroup>

## Using the LangChain Adapter

The `LangChainAdapter` is a powerful component that converts MCP tools to LangChain tools, enabling you to use MCP tools with any LangChain-compatible agent.

<Note>
**Simplified API**: The LangChain adapter provides a streamlined API that handles all the complexity of session management, connector initialization, and tool conversion automatically.
</Note>

### Basic Example

Here's a simple example of creating a custom agent using the LangChain adapter:

<CodeGroup>
```typescript TypeScript
import { ChatOpenAI } from '@langchain/openai'
import { AgentExecutor, createToolCallingAgent } from 'langchain/agents'
import { ChatPromptTemplate, MessagesPlaceholder } from '@langchain/core/prompts'
import { MCPClient, LangChainAdapter, loadConfigFile } from 'mcp-use'

async function main() {
    // Initialize the MCP client
    const config = await loadConfigFile('path/to/config.json')
    const client = new MCPClient(config)

    // Create adapter instance
    const adapter = new LangChainAdapter()

    // Get LangChain tools directly from the client with a single line
    const tools = await adapter.createTools(client)

    // Initialize your language model
    const llm = new ChatOpenAI({ model: 'gpt-4o' })

    // Create a prompt template
    const prompt = ChatPromptTemplate.fromMessages([
        ['system', 'You are a helpful assistant with access to powerful tools.'],
        new MessagesPlaceholder('chat_history'),
        ['human', '{input}'],
        new MessagesPlaceholder('agent_scratchpad'),
    ])

    // Create the agent
    const agent = createToolCallingAgent({ llm, tools, prompt })

    // Create the agent executor
    const agentExecutor = new AgentExecutor({ agent, tools, verbose: true })

    // Run the agent
    const result = await agentExecutor.invoke({ input: 'What can you do?' })
    console.log(result.output)

    await client.closeAllSessions()
}

main().catch(console.error)
```

```typescript TypeScript
import { ChatOpenAI } from '@langchain/openai'
import { AgentExecutor, createToolCallingAgent } from 'langchain/agents'
import { ChatPromptTemplate, MessagesPlaceholder } from '@langchain/core/prompts'
import { MCPClient, LangChainAdapter, loadConfigFile } from 'mcp-use'

async function main() {
    // Initialize the MCP client
    const config = await loadConfigFile('path/to/config.json')
    const client = new MCPClient(config)

    // Create adapter instance
    const adapter = new LangChainAdapter()

    // Get LangChain tools directly from the client with a single line
    const tools = await adapter.createTools(client)

    // Initialize your language model
    const llm = new ChatOpenAI({ model: 'gpt-4o' })

    // Create a prompt template
    const prompt = ChatPromptTemplate.fromMessages([
        ['system', 'You are a helpful assistant with access to powerful tools.'],
        new MessagesPlaceholder('chat_history'),
        ['human', '{input}'],
        new MessagesPlaceholder('agent_scratchpad'),
    ])

    // Create the agent
    const agent = createToolCallingAgent({ llm, tools, prompt })

    // Create the agent executor
    const agentExecutor = new AgentExecutor({ agent, tools, verbose: true })

    // Run the agent
    const result = await agentExecutor.invoke({ input: 'What can you do?' })
    console.log(result.output)

    await client.closeAllSessions()
}

main().catch(console.error)
```
</CodeGroup>

<Tip>
**One-Line Tool Creation**: The API simplifies tool creation - all you need is to create an adapter instance and call its `create_tools` method:

<CodeGroup>
```typescript TypeScript
const adapter = new LangChainAdapter()
const tools = await adapter.createTools(client)
```

```typescript TypeScript
const adapter = new LangChainAdapter()
const tools = await adapter.createTools(client)
```
</CodeGroup>

You don't need to worry about sessions, connectors, or initialization. The adapter handles everything for you.
</Tip>

## Contributing New Adapters

<Info>
MCP-Use welcomes contributions for integrating with different agent frameworks! The adapter architecture is designed to make this process straightforward and requires minimal implementation effort.
</Info>

### Adapter Architecture

MCP-Use provides a `BaseAdapter` abstract class that handles most of the common functionality:

<CardGroup cols={2}>
  <Card title="Automatic Handling" icon="magic">
    - Tool caching management
    - Connector initialization
    - Multi-connector iteration
  </Card>
  <Card title="Simple Implementation" icon="code">
    Only implement `_convert_tool` method to convert MCP tools to your framework's format
  </Card>
</CardGroup>

<Warning>
**Single Required Method**: To create an adapter for a new framework, you only need to implement one method: `_convert_tool` to convert a single MCP tool to your framework's tool format.
</Warning>

### Creating a New Adapter

Here's a simple template for creating a new adapter:

### Using Your Custom Adapter

Once you've implemented your adapter, you can use it with the simplified API:

<CodeGroup>
```typescript TypeScript
import { YourFrameworkAdapter } from './your-module'
import { MCPClient, loadConfigFile } from 'mcp-use'

// Initialize the client
const config = await loadConfigFile('config.json')
const client = new MCPClient(config)

// Create an adapter instance
const adapter = new YourFrameworkAdapter()

// Get tools with a single line
const tools = await adapter.createTools(client)

// Use the tools with your framework
const agent = yourFramework.createAgent({ tools })
```

```typescript TypeScript
import { YourFrameworkAdapter } from './your-module'
import { MCPClient, loadConfigFile } from 'mcp-use'

// Initialize the client
const config = await loadConfigFile('config.json')
const client = new MCPClient(config)

// Create an adapter instance
const adapter = new YourFrameworkAdapter()

// Get tools with a single line
const tools = await adapter.createTools(client)

// Use the tools with your framework
const agent = yourFramework.createAgent({ tools })
```
</CodeGroup>

### Tips for Implementing an Adapter

<AccordionGroup>
  <Accordion title="Schema Conversion">
    Most frameworks have their own way of handling argument schemas. You'll need to convert the MCP tool's JSON Schema to your framework's format.

    <Tip>
    Look at the LangChain adapter implementation as a reference for handling schema conversion patterns.
    </Tip>
  </Accordion>

  <Accordion title="Tool Execution">
    When a tool is called in your framework, you'll need to pass the call to the connector's `call_tool` method and handle the result.

    <Warning>
    Always ensure proper async/await handling when calling MCP tools, as they are inherently asynchronous.
    </Warning>
  </Accordion>

  <Accordion title="Result Parsing">
    MCP tools return structured data with types like text, images, or embedded resources. Your adapter should parse these into a format your framework understands.
  </Accordion>

  <Accordion title="Error Handling">
    Ensure your adapter handles errors gracefully, both during tool conversion and execution.

    <Note>
    The base adapter provides logging utilities to help with error reporting and debugging.
    </Note>
  </Accordion>
</AccordionGroup>

## Conclusion

<CardGroup cols={2}>
  <Card title="Maximum Flexibility" icon="expand">
    Build specialized agents tailored to your specific tasks or integrate MCP capabilities into existing systems
  </Card>
  <Card title="Simple Architecture" icon="puzzle-piece">
    Easy extension with minimal implementation - just one `_convert_tool` method needed
  </Card>
</CardGroup>

<Info>
**Key Benefits:**
- **Simplified API**: Create tools directly from MCPClient with a single method call
- **Automatic Management**: Session and connector complexity is handled automatically
- **Flexible Integration**: Works with any agent framework that has a LangChain-style interface
</Info>

<Tip>
**Contributing Back**: We welcome contributions to expand the adapter ecosystem! If you develop an adapter for a new framework, please consider contributing it back to the project to help the community.
</Tip>
